<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />

  <title>Cocos Creator | HanziVertical</title>

  <!--http://www.html5rocks.com/en/mobile/mobifying/-->
  <meta name="viewport"
    content="width=device-width,user-scalable=no,initial-scale=1, minimum-scale=1,maximum-scale=1" />

  <!--https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html-->
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
  <meta name="format-detection" content="telephone=no" />

  <!-- force webkit on 360 -->
  <meta name="renderer" content="webkit" />
  <meta name="force-rendering" content="webkit" />
  <!-- force edge on IE -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="msapplication-tap-highlight" content="no" />

  <!-- force full screen on some browser -->
  <meta name="full-screen" content="yes" />
  <meta name="x5-fullscreen" content="true" />
  <meta name="360-fullscreen" content="true" />

  <!-- force screen orientation on some browser -->
  <meta name="screen-orientation" content="portrait" />
  <meta name="x5-orientation" content="portrait" />

  <!--fix fireball/issues/3568 -->
  <!--<meta name="browsermode" content="application">-->
  <meta name="x5-page-mode" content="app" />

  <!--<link rel="apple-touch-icon" href=".png" />-->
  <!--<link rel="apple-touch-icon-precomposed" href=".png" />-->

  <link rel="stylesheet" type="text/css" href="style-mobile.css" />
  <link rel="stylesheet" type="text/css" href="index.css" />
  <link rel="icon" href="favicon.ico" />
</head>

<body>
  <canvas id="GameCanvas" oncontextmenu="event.preventDefault()" tabindex="0"></canvas>
  <div id="splash">
    <div class="progress-bar stripes">
      <span style="width: 0%"></span>
    </div>
  </div>
  <div class="floating-btn" onclick="showModal()">关卡配置</div>

  <!-- Modal Overlay -->
  <div class="modal-overlay" id="modalOverlay" onclick="hideModal()"></div>

  <!-- Modal Content -->
  <div class="modal-content" id="modalContent">
    <div class="modal-panel" style="min-height: 100px;">
      <select id="libSelect" style="text-align: center; margin-bottom: 10px;width: 100%;" onchange="onLibSelectChanged(event)">
        <option value="all">所有关卡</option>
        <option value="offline">未排布关卡</option>
        <option value="other">非当前分组</option>
        <option value="issue">问题关卡</option>
      </select>
      <ul id="lib-list"></ul>
    </div>
    <div style="width: 5px"></div>
    <div class="modal-panel" style="width: 100%;">
      <div class="tab_head" style="display:flex; flex-direction: row;">
        <div id="tab_order" class="tab_button tab_left" onclick="onTab(0)">顺序配置</div>
        <div id="tab_recommend" class="tab_button tab_middle" onclick="onTab(1)">推荐配置</div>
        <div id="tab_ad" class="tab_button tab_right" onclick="onTab(2)">广告关联</div>
      </div>
      <div id="order-content" style="display: flex; flex-direction: column; height: 100%; max-width: 100%;">
        <div style="display: flex; align-items: center">
          <!-- <select id="mySelect"></select> -->
          <div style="flex: 1"></div>
          <lable style="font-weight:bold;">历史导出:</lable>
          <select id="export-select" style="font-size:medium;font-weight: normal;"></select>
          <div class="normal-btn" onclick="exportData()">导出</div>
          <div class="normal-btn" onclick="importData()" title="导入功能延时保留，后续会移除">导入</div>
        </div>
        <div style="display: flex;flex-direction: row;max-height: calc(100% - 90px);height: 100%;">
          <div style="display: flex;flex-direction: column;width: 100%;margin-right: 2px;height: 100%;">
            <div class="table-header">
              <span>顺序</span>
              <span>名称</span>
              <span>页数</span>
            </div>
            <ul id="sortable-list" class="li-before li-after" tabindex="100">
              <!-- The array content will be dynamically added here -->
            </ul>
          </div>
          <div style="display: flex;flex-direction: column;width: 300px;">
            <div class="table-header">关卡组</div>
            <ul id="order-group-list-0" class="li-before" tabindex="101" style="padding: 0; margin: 0; height: 100%;"></ul>
            <li style="display: flex;flex-direction: row;"><input id="order-group-name-input" style="width: 100px;height: 30px;margin-right: 8px;" placeholder="分组名称"/><button style="flex: 1;" onclick="onCreatOrderGroup()">创建</button></li>
          </div>
        </div>
      </div>
      <div id="recommend-content" style="display: flex;flex-direction: column;height: 100%;">
        <div style="display: flex; align-items: center">
          <div style="display: flex; margin-top: 5px;">
            <label style="font-weight: bold;">总开关:<input id="isOpenRecommond" type="checkbox" onchange="onSwitchChanged(event)" checked style="margin-right: 20px;"/></label>
            <label style="font-weight: bold;">关卡组随机:<input id="isOpenGroupRandom" type="checkbox" onchange="onSwitchChanged(event)" style="margin-right: 20px;"/></label>
            <label style="font-weight: bold;">组内关卡随机:<input id="isOpenLevelRandom" type="checkbox" onchange="onSwitchChanged(event)" style="margin-right: 20px;"/></label>
            <label style="font-weight: bold;">触发次数:<input id="recommondRound" type="number" value="5" onchange="onInputChanged(event)" style="width: 50px;margin-right: 20px;"/></label>
            <label style="font-weight: bold;">玩家任务数:<input id="recommondRewardRound" type="number" value="3" onchange="onInputChanged(event)" style="width: 50px;margin-right: 20px;"/></label>
            <label style="font-weight: bold;">推荐关卡数:<input id="randomLevelNum" type="number" value="2" onchange="onInputChanged(event)" style="width: 50px;margin-right: 15px;"/></label>
          </div>
          <div style="flex: 1"></div>
          <lable style="font-weight:bold;">历史导出:</lable>
          <select id="export-group-select" style="font-size:medium;font-weight: normal;"></select>
          <div class="normal-btn" onclick="exportGroupData()">导出</div>
          <div class="normal-btn" onclick="importGroupData()" title="导入功能延时保留，后续会移除">导入</div>
        </div>
        <div style="display: flex;flex-direction: row;height: calc(100% - 50px);">
          <div style="display: flex;flex-direction: column;width: 100%;margin-right: 2px;">
            <div class="table-header">组内关卡</div>
            <ul id="group-level-list" class="li-before" tabindex="200"></ul>
          </div>
          <div style="display: flex;flex-direction: column;width: 300px;">
            <div class="table-header">推荐组</div>
            <ul id="group-list" class="li-before" tabindex="201"></ul>
            <li style="display: flex;flex-direction: row;"><input id="group-name-input" style="width: 100px;height: 30px;margin-right: 8px;" placeholder="分组名称"/><button style="flex: 1;" onclick="onCreatGroup()">创建</button></li>
          </div>
        </div>
        
      </div>
      <div id="ad-content" style="display: flex; flex-direction: column; height: 100%; max-width: 100%;">
        <div style="display: flex; align-items: center">
          <!-- <select id="mySelect"></select> -->
          <div style="flex: 1"></div>
          <lable style="font-weight:bold;">历史导出:</lable>
          <select id="ad-export-select" style="font-size:medium;font-weight: normal;"></select>
          <div class="normal-btn" onclick="exportAdData()">导出</div>
          <div class="normal-btn" onclick="importAdData()" title="导入功能延时保留，后续会移除">导入</div>
        </div>
        <div style="display: flex;flex-direction: row;max-height: 100%;height: 100%;">
          <div style="display: flex;flex-direction: column;width: 100%;margin-right: 2px;height: 100%;">
            <div class="table-header">
              <span>广告id列表</span>
              <span>跳转到目标组</span>
            </div>
            <ul id="ad-level-list" class="li-before" tabindex="300"></ul>
            <li style="display: flex;flex-direction: row;"><div style="flex:1"></div><input id="ad-id-input" style="width: 130px;height: 30px;margin-right: 8px;" placeholder="广告ID"/><button style="width: max-content;padding: 5px 20px;" onclick="onAddAd()">添加</button></li>
          </div>

          <div style="display: flex;flex-direction: column;width: 300px;">
            <div class="table-header">关卡组</div>
            <ul id="order-group-list-2" class="li-before" tabindex="301" style="padding: 0; margin: 0; height: 100%;"></ul>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="toast" id="toast">这是一个 Toast 提示</div>

  <script src="md5.js" charset="utf-8"></script>
  <script>
    function getQueryVariable(variable)
    {
        var query = window.location.search.substring(1);
        var vars = query.split("&");
        for (var i=0;i<vars.length;i++) {
            var pair = vars[i].split("=");
            if(pair[0] == variable){return pair[1];}
        }
        return(false);
    }
  </script>
  <script>
    document.write(`<script src="src/settings.${getQueryVariable("v")}.js" charset="utf-8"><\/script>`);
    document.write(`<script src="main.${getQueryVariable("v")}.js" charset="utf-8"><\/script>`);
  </script>
  <!-- <script src="test.js"></script> -->
  <script src="recommend.js"></script>
  <script src="ad.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
  <script type="text/javascript">
    (function () {
      // open web debugger console
      if (typeof VConsole !== "undefined") {
        window.vConsole = new VConsole();
      }

      var debug = window._CCSettings.debug;
      var splash = document.getElementById("splash");
      splash.style.display = "block";

      function loadScript(moduleName, cb) {
        function scriptLoaded() {
          document.body.removeChild(domScript);
          domScript.removeEventListener("load", scriptLoaded, false);
          cb && cb();
        }
        var domScript = document.createElement("script");
        domScript.async = true;
        domScript.src = moduleName;
        domScript.addEventListener("load", scriptLoaded, false);
        document.body.appendChild(domScript);
      }

      loadScript(
        debug ? "cocos2d-js.js" : "cocos2d-js-min.2bfb8.js",
        function () {
          if (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) {
            loadScript(debug ? "physics.js" : "physics-min.js", window.boot);
          } else {
            window.boot();
          }
        }
      );
    })();
  </script>
  <script>
    const itemType = [
      {type:"计时", times:"总时长:", addTimesByAd:"补时时长:"},
      {type:"错误次数", times:"允许错误:"},
    ]
    var currentSelectOrderGroupIndex = 0;
    function copyAllLevel() {
      if(window['dataArray']) {
        return;
      }
      let dataArray = [];
      let levelItemData = window['LevelItemData'];
      for (let i = 0; i < levelItemData.length; i++) {
        const levelInfo = levelItemData[i];
        dataArray[i] = {name:levelInfo.name, levels:levelInfo.levels.concat()}
      }
      window['dataArray'] = dataArray;
    }
    
    //获取所有关卡，并排除传入的关卡
    function getAllLevels(excludeLevels, dataArray) {
      excludeLevels = excludeLevels || [];
      dataArray = dataArray || window['dataArray'];
      const libListElement = document.getElementById("lib-list");
      // if(libListElement.innerHTML == "") {
      //   dataArray = window["LevelItemData"].concat();
      // }
      let all_levels = {};
      if(excludeLevels && excludeLevels.length > 0) {
        excludeLevels = excludeLevels.map(item=> item.tag);
      }
      for (let i = 0; i < dataArray.length; i++) {
        const typeLevels = dataArray[i]['levels'];
        for (let j = 0; j < typeLevels.length; j++) {
          const level = typeLevels[j];
          if(!excludeLevels.includes(level.tag)){
              all_levels[level.tag] = level;
          }
        }
      }
      return all_levels;
    }

    async function onLibSelectChanged(event) {
      const selectElement = document.getElementById("libSelect");
      let all_levels = {}
      //全部关卡
      if (selectElement.value == "all") {
        all_levels = getAllLevels();
      }
      //未上架
      else if(selectElement.value == "offline") {
        let onlineArr = [];
        let online = window["LevelItemData"];
        for (let i = 0; i < online.length; i++) {
          const group = online[i];
          for (let j = 0; j < group["levels"].length; j++) {
            const element = group["levels"][j];
            onlineArr.push(element);
          }
        }
        all_levels = getAllLevels(onlineArr);
      }
      //非当前分类关卡
      else if(selectElement.value == "other") {
          var dataArray = window["LevelItemData"][currentSelectOrderGroupIndex]["levels"];
          all_levels = getAllLevels(dataArray);
      }else {
        let jsonData = window['issue_level'];
        if(!jsonData){
          const response = await fetch("issue_level.json?" + Date.now())
          jsonData = await response.json();
          window['issue_level'] = jsonData;
        }
        for (let i = 0; i < jsonData.length; i++) {
          const level = jsonData[i];
          all_levels[level['tag']] = level;
        }
      }
      initLibList(all_levels)
    }

    function showModal() {
      document.getElementById("modalOverlay").style.display = "block";
      document.getElementById("modalContent").style.display = "flex";
      const selectElement = document.getElementById("export-select");
      if(selectElement.innerHTML != "") {
        return;
      }
      copyAllLevel();
      initLibList();
      onTab(0);
    }

    function updateList() {
      const listElement = document.getElementById("sortable-list");
      listElement.innerHTML = "";
      var dataArray = window["LevelItemData"][currentSelectOrderGroupIndex]["levels"];
      let allLevels = getAllLevels();
      for (var i = dataArray.length - 1; i >= 0; i--) {
        var item = dataArray[i];
        const listItem = document.createElement("li");
        listItem.style.display = "flex";
        listItem.setAttribute("data-index", dataArray.length - i);
        listItem.setAttribute(
          "data-page-number",
          Math.floor((dataArray.length - i - 1) / 6) + 1
        );
        listItem.setAttribute("data-item", JSON.stringify(item));

        const label = document.createElement("div");
        label.className = "level-title";
        if(allLevels[item.tag] && allLevels[item.tag]['external']) {
          label.style.color = "#63bfe4";
        }
        label.textContent = item['tag'] + ":" + item["subTitle"];
        label.style.pointerEvents = "none";
        listItem.appendChild(label);

        const div = document.createElement("div");
        div.style.flex = 1;
        div.style.pointerEvents = "none";
        listItem.appendChild(div);

        if (item['gameType'] == 1 || item['gameType'] == 0){
          const timesLable = document.createElement("div");
          timesLable.textContent = itemType[item['gameType']].times;
          listItem.append(timesLable);
          const timesInput = document.createElement("input");
          timesInput.type = "number";
          timesInput.className = "input-number";
          timesInput.value = item["times"];
          timesInput.onchange = (ev)=>{
            let data = JSON.parse(ev.target.parentElement.getAttribute("data-item"));
            data['times'] = ev.target.value;
            ev.target.parentElement.setAttribute("data-item", JSON.stringify(data));
            let dataArray = window['LevelItemData'];
            for (let group = 0; group < dataArray.length; group++) {
              const groupInfo = dataArray[group];
              for (let i = 0; i < groupInfo.levels.length; i++) {
                const levelInfo = groupInfo.levels[i];
                if(levelInfo['tag'] == data['tag']) {
                  levelInfo['times'] = data['times'];    
                }
              }
            }
          }
          listItem.appendChild(timesInput);
        }
  
        if (item['gameType'] == 0){
          const addTimesLable = document.createElement("div");
          addTimesLable.textContent = itemType[item['gameType']].addTimesByAd;
          listItem.append(addTimesLable);
          const addTimesByAdInput = document.createElement("input");
          addTimesByAdInput.className = "input-number";
          addTimesByAdInput.type = "number";
          addTimesByAdInput.value = item["addTimesByAd"];
          listItem.appendChild(addTimesByAdInput);
        }  
        const checkbox = document.createElement("input");
        checkbox.type = "checkbox";
        checkbox.style.setProperty("padding-left", "10px");
        checkbox.checked = item['enterTipUI'] != null;
        listItem.appendChild(checkbox);
        checkbox.onchange = (ev)=>{
          let data = JSON.parse(ev.target.parentElement.getAttribute("data-item"));
          data['enterTipUI'] = ev.target.checked ? 18 : null;
          ev.target.parentElement.setAttribute("data-item", JSON.stringify(data));
          let dataArray = window['LevelItemData'];
          for (let group = 0; group < dataArray.length; group++) {
            const groupInfo = dataArray[group];
            for (let i = 0; i < groupInfo.levels.length; i++) {
              const levelInfo = groupInfo.levels[i];
              if(levelInfo['tag'] == data['tag']) {
                levelInfo['enterTipUI'] = data['enterTipUI'];    
              }
            }
          }
        }

        const checkBoxLable = document.createElement("div");
        checkBoxLable.textContent = "微恐";
        listItem.appendChild(checkBoxLable);
        createFlagDrop(item, listItem);
        createLv(item, listItem);
        createPoint(item, listItem);
        createDarenDrop(item, listItem);
        const div1 = document.createElement("div");
        div1.style.width = "5%";
        listItem.appendChild(div1);

        listElement.appendChild(listItem);
      }
    }

    function createLv(item, listItem) {
      const flagLabel = document.createElement("div");
      flagLabel.textContent = "难度:";
      listItem.appendChild(flagLabel);
      flagLabel.style.setProperty("padding-left", "10px");

      const flagDrop = document.createElement("select");
      const levelLvs = ['简单', '中等', '较难']
      for (let i = 0; i < levelLvs.length; i++) {
        const option = document.createElement("option");
        option.value = i + 1;
        option.selected = item['levelLv'] == i + 1;
        option.innerHTML = levelLvs[i];
        flagDrop.appendChild(option);
      }
      flagDrop.className = "flag-select"
      listItem.appendChild(flagDrop);
      flagDrop.onchange = (ev)=>{
          let data = JSON.parse(ev.target.parentElement.getAttribute("data-item"));
          let levelLv = Number(flagDrop.selectedOptions[0].value);
          data['levelLv'] = levelLv;
          ev.target.parentElement.setAttribute("data-item", JSON.stringify(data));
          let dataArray = window['LevelItemData'];
          for (let group = 0; group < dataArray.length; group++) {
            const groupInfo = dataArray[group];
            for (let i = 0; i < groupInfo.levels.length; i++) {
              const levelInfo = groupInfo.levels[i];
              if(levelInfo['tag'] == data['tag']) {
                levelInfo['levelLv'] = levelLv;
              }
            }
          }
      }
    }

    function createPoint(item, listItem) {
      const flagLabel = document.createElement("div");
      flagLabel.textContent = "评分:";
      listItem.appendChild(flagLabel);
      flagLabel.style.setProperty("padding-left", "10px");

      const pointInput = document.createElement("input");
      pointInput.type = 'number';
      pointInput.className = "input-number";
      pointInput.value = item['levelPoint'] || 9;
      pointInput.style.width = '30px';
      listItem.appendChild(pointInput);
      pointInput.onchange = (ev)=>{
          let data = JSON.parse(ev.target.parentElement.getAttribute("data-item"));
          let point = pointInput.value;
          data['levelPoint'] = Number(point);
          ev.target.parentElement.setAttribute("data-item", JSON.stringify(data));
          let dataArray = window['LevelItemData'];
          for (let group = 0; group < dataArray.length; group++) {
            const groupInfo = dataArray[group];
            for (let i = 0; i < groupInfo.levels.length; i++) {
              const levelInfo = groupInfo.levels[i];
              if(levelInfo['tag'] == data['tag']) {
                levelInfo['levelPoint'] = point;
              }
            }
          }
      }
    }

    /**
     * 标签下拉框
     * */
    function createFlagDrop(item, listItem) {
      const flagLabel = document.createElement("div");
      flagLabel.textContent = "标签:";
      listItem.appendChild(flagLabel);
      flagLabel.style.setProperty("padding-left", "10px");

      const flagDrop = document.createElement("select");
      const noneOption = document.createElement("option");
      noneOption.value = "NONE";
      noneOption.innerHTML = "无";
      flagDrop.appendChild(noneOption);
      const newOption = document.createElement("option");
      newOption.value = "NEW";
      newOption.innerHTML = "NEW";
      newOption.selected = item['isNew'];
      flagDrop.appendChild(newOption);
      const hotOption = document.createElement("option");
      hotOption.value = "HOT";
      hotOption.innerHTML = "HOT";
      hotOption.selected = item['isHot'];
      flagDrop.appendChild(hotOption);
      flagDrop.className = "flag-select"
      listItem.appendChild(flagDrop);
      flagDrop.onchange = (ev)=>{
          let data = JSON.parse(ev.target.parentElement.getAttribute("data-item"));
          let flag = flagDrop.selectedOptions[0].value;
          delete data['isNew'];
          delete data['isHot'];
          if (flag == "HOT") {
            data['isHot'] = true;
          } else if(flag == "NEW") {
            data['isNew'] = true;
          }
          ev.target.parentElement.setAttribute("data-item", JSON.stringify(data));
          let dataArray = window['LevelItemData'];
          for (let group = 0; group < dataArray.length; group++) {
            const groupInfo = dataArray[group];
            for (let i = 0; i < groupInfo.levels.length; i++) {
              const levelInfo = groupInfo.levels[i];
              if(levelInfo['tag'] == data['tag']) {
                delete levelInfo['isNew'];
                delete levelInfo['isHot'];
                if (flag == "HOT") {
                  levelInfo['isHot'] = true;
                } else if(flag == "NEW") {
                  levelInfo['isNew'] = true;
                }
              }
            }
          }
      }
    }

    /**
     * 贴脸关卡
     * */
    function createDarenDrop(item, listItem) {
      const checkbox = document.createElement("input");
        checkbox.type = "checkbox";
        checkbox.checked = item['isActivity'];
        checkbox.style.setProperty("padding-left", "15px");
        listItem.appendChild(checkbox);
        checkbox.onchange = (ev)=>{
          let data = JSON.parse(ev.target.parentElement.getAttribute("data-item"));
          if(ev.target.checked){
            data['isActivity'] = true;
          }else{
            delete data['isActivity'];
          }
          ev.target.parentElement.setAttribute("data-item", JSON.stringify(data));
          let dataArray = window['LevelItemData'];
          for (let group = 0; group < dataArray.length; group++) {
            const groupInfo = dataArray[group];
            for (let i = 0; i < groupInfo.levels.length; i++) {
              const levelInfo = groupInfo.levels[i];
              if(levelInfo['tag'] == data['tag']) {
                if(ev.target.checked){
                  levelInfo['isActivity'] = true;
                }else{
                  delete levelInfo['isActivity'];
                }
              }
            }
          }
        }

      const checkBoxDaren = document.createElement("div");
      checkBoxDaren.textContent = "弹框推荐";
      listItem.appendChild(checkBoxDaren);
    }

    function hideModal() {
      document.getElementById("modalOverlay").style.display = "none";
      document.getElementById("modalContent").style.display = "none";
    }

    function initializeSortableList() {
      let sortable_list = document.getElementById("sortable-list")
      new Sortable(sortable_list, {
        group: 'shared',
        animation: 150, // Animation speed in milliseconds
        onEnd: onEndDrag,
      });

      sortable_list.addEventListener('click', function (event) {
        const target = event.target;
        if (target.tagName === 'LI') {
          target.classList.toggle('li-selected');
          sortable_list.focus();
        }
      });

      sortable_list.addEventListener('keydown', function (event) {
        if(event.target != sortable_list){
            return;
        }
        const keyCode = event.keyCode || event.which;
        if (keyCode === 46 || keyCode === 8) {
          // 获取选中的项
          const listItems = document.querySelectorAll("#sortable-list li");
          const selectedItems = Array.from(listItems).filter(item => item.classList.contains('li-selected'));
          selectedItems.forEach(item => item.remove());
          onEndDrag();
        }
      });
    }

    function onEndDrag() {
      var dataArray = window["LevelItemData"][currentSelectOrderGroupIndex]["levels"];
      dataArray.length = 0;
      const listItems = document.querySelectorAll("#sortable-list li");
      for (let i = listItems.length - 1; i >= 0; i--) {
        const element = listItems[i];
        var data = JSON.parse(element.getAttribute("data-item"));
        dataArray.push(data);
      }
      updateList();
    }

    function initLibList(all_levels) {
      const libListElement = document.getElementById("lib-list");
      // if (libListElement.innerHTML != "") {
      //   return;
      // }
      libListElement.innerHTML = "";
      all_levels = all_levels || getAllLevels();

      new Sortable(document.getElementById("lib-list"), {
        group: {
          name: 'shared',
          pull: 'clone',
          put: false // Do not allow items to be put into this list
        },
        sort: false,
        animation: 150,
        onEnd: function (evt) {
          // 获取拖拽的源列表和目标列表
          const sourceList = evt.from;
          const targetList = evt.to;
          if (targetList.id == "sortable-list") {
            onEndDrag()
          }
        }
      });

      var tags = Object.keys(all_levels)
      tags = tags.sort((a, b) => b - a)
      for (const tag of tags) {
        var level = all_levels[tag]
        const listItem = document.createElement("li");
        listItem.setAttribute("data-item", JSON.stringify(level));
        listItem.textContent = `${level['tag']}:${level["subTitle"]}`;
        if(level['external']) {
          listItem.style.color = "#63bfe4";
        }
        libListElement.appendChild(listItem);
      }
    }

    function initSelect(targetIndex=0) {
      var group_list = document.getElementById("order-group-list-"+tabIndex);
      if (group_list.innerHTML == "") {
          initOrderGroupList(tabIndex);
      }
      group_list.innerHTML = "";
      levelData = window["LevelItemData"];
      let selectListItem;
      for (let i = 0; i < levelData.length; i++) {
        const element = levelData[i];
        const listItem = document.createElement("li");
        listItem.style = "display: flex;flex-direction: row;";
        listItem.setAttribute("data-index", i);

        //分组名称
        const label = document.createElement("div");
        label.className = "level-title";
        label.textContent = `${i < 6 ? "固定:" : "自定义:"}${element.name}`;
        label.style.pointerEvents = "none";
        listItem.appendChild(label);
        group_list.appendChild(listItem);
        i == targetIndex && (selectListItem = listItem);

        // const newOption = document.createElement("option");
        // newOption.value = i;
        // newOption.textContent = element.name;
        // selectElement.appendChild(newOption);
      }
      onOrderGroupSelect(selectListItem);
      // selectElement.selectedIndex = selectIndex == -1 ? 0 : selectIndex;
      // selectElement.addEventListener("change", function () {
      //   const selectedValue = selectElement.value;
      //   updateList();
      //   onLibSelectChanged();
      // });
    }

    function onOrderGroupSelect(target){
      currentSelectOrderGroupIndex = Number(target.getAttribute("data-index"));
      const listItems = document.querySelectorAll(`#order-group-list-${tabIndex} li`);
      for (let i = 0; i < listItems.length; i++) {
          const element = listItems[i];
          let itemName = element.getAttribute("data-item");
          element.classList.remove('li-selected');
      }
      target.classList.add('li-selected');
      if(tabIndex == 0){
        updateList();
        onLibSelectChanged();
      }else if(tabIndex == 2) {
        updateAdList();
      }
    }

    function initOrderGroupList() {
      let targetId = "order-group-list-"+tabIndex
      var sortable_list = document.getElementById(targetId)
      new Sortable(sortable_list, { name:"group",
          pull: false,
          put: false,
          sort: false,
          animation: 150, // Animation speed in milliseconds
          onEnd: onGroupEndDrag,
      });
      sortable_list.addEventListener('click', function (event) {
          const target = event.target;
          if (target.tagName === 'LI') {
            onOrderGroupSelect(target);
            sortable_list.focus();
          }
      });

      sortable_list.addEventListener('keydown', function (event) {
          if(event.target != sortable_list){
              return;
          }
          if(tabIndex != 0){
            showToast("请在顺序配置分页中编辑关卡组");
            return;
          }
          const keyCode = event.keyCode || event.which;
          if (keyCode === 46 || keyCode === 8) {
              // 获取选中的项
              let listItems = document.querySelectorAll(`#${targetId} li`);
              const selectedItems = Array.from(listItems).filter(item => item.classList.contains('li-selected'));
              let protectGroups = selectedItems.filter(item => item.getAttribute('data-index') < 6)
              if(protectGroups.length){
                showToast("固定分组无法删除");
                return;
              }
              selectedItems.forEach(item => item.remove());
              listItems = document.querySelectorAll(`#${targetId} li`);
              onOrderGroupSelect(listItems.length ? listItems[0] : null);
          }
      });
    }

    function onCreatOrderGroup() {
      let newGroupName = document.getElementById('order-group-name-input').value;
      if(!newGroupName){
          showToast("请输入组名");
          return
      }
      let hasExist = window["LevelItemData"].filter(value=>value.name==newGroupName);
      if(hasExist && hasExist.length){
          showToast("有重名的组："+ newGroupName);
          return
      }
      let newGroupData = {name: newGroupName, levels: []};
      window["LevelItemData"].push(newGroupData);
      initSelect(window["LevelItemData"].length - 1);
      updateList();
    }

    function parseFile(event) {
      const file = event.target.files[0];
      const reader = new FileReader();
      reader.onload = function (event) {
        const jsonStr = event.target.result;
        try {
          const jsonData = JSON.parse(jsonStr);
          console.log(jsonData);
        } catch (error) {
          console.error('无法解析 JSON 文件:', error);
        }
      };
      reader.readAsText(file);
    }

    function importData() {
      const fileInput = document.createElement('input');
      fileInput.type = 'file';
      fileInput.addEventListener('change', (event) => {
        const file = event.target.files[0];
        const reader = new FileReader();
        reader.onload = function (event) {
          const jsonStr = event.target.result;
          fileInput.remove();
          const jsonData = JSON.parse(jsonStr);
          console.log("导入：", jsonData);
          var dataArray = window["LevelItemData"];
          //替换最新关卡数据到导入的关卡数据中，确保单个关卡数据为最新内容。
          let length = Math.max(jsonData.length, dataArray.length);
          for (let i = 0; i < jsonData.length; i++) {
            dataArray[i] = jsonData[i];
          }
          dataArray.length = jsonData.length;
          currentSelectOrderGroupIndex = 0;
          initSelect();
          updateList();
          showToast("数据导入成功!");
        };
        reader.readAsText(file);
      });
      fileInput.click();
    }

    function exportData() {
      let dataArray = window["LevelItemData"];
      console.log("打印最新关卡顺序:", dataArray);
      for (let group = 0; group < dataArray.length; group++) {
        const groupInfo = dataArray[group];
        let countDict = {};
        for (let i = 0; i < groupInfo.levels.length; i++) {
          const levelInfo = groupInfo.levels[i];
          countDict[levelInfo.tag] = countDict[levelInfo.tag] || 0;
          countDict[levelInfo.tag] += 1;
          if(countDict[levelInfo.tag] >= 2){
            showToast(`【${groupInfo.name}】分组中《${levelInfo.subTitle}》关卡重复`)
            return;
          }
        }
      }
      
      const jsonString = JSON.stringify(dataArray);
      const dataURL = 'data:application/json;charset=utf-8,' + encodeURIComponent(jsonString);
      
      const a = document.createElement('a');
      a.href = dataURL;
      let flag = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
      flag = flag.replace(/:/g, ".").replace(/\//g, ".").replace(" ", "_")
      let md5 = saveLevelOrderToLocal();
      a.download = `lv_${md5}_${flag}.json`;
      a.click();
      a.remove();
      showToast("成功！发送下载目录的导出文件给程序。");
    }

    function saveLevelOrderToLocal(des="无描述") {
      let dataArray = window["LevelItemData"];
      let levelOrder = [];
      let groupNames = [];
      for (let i = 0; i < dataArray.length; i++) {
        const chapterInfo = dataArray[i];
        groupNames.push(chapterInfo.name);
        let chapterOrder = levelOrder[i] = [];
        for (let index = 0; index < chapterInfo.levels.length; index++) {
          const levelInfo = chapterInfo.levels[index];
          chapterOrder[index] = levelInfo.tag;
        }
      }
      let orderStr = JSON.stringify(levelOrder);
      let md5 = window.hex_md5(orderStr);
      md5 = md5.substring(md5.length - 6, md5.length)
      navigator.clipboard.writeText(`版本:${md5}\n顺序:\n${orderStr}`);
      let exportAllLevels = getAllLevels(null, window["LevelItemData"])
      
      let exportList = localStorage.getItem("export_list") || "[]";
      exportList = JSON.parse(exportList);
      exportList.push({des:des,md5:md5,time:Date.now(), order:levelOrder, levels:exportAllLevels, names:groupNames});
      if(exportList.length > 10){
        exportList.splice(0, 10-exportList.length)
      }
      localStorage.setItem("export_list", JSON.stringify(exportList));
      initExportSelect();
      
      return md5;
    }

    function initExportSelect() {
      let exportList = localStorage.getItem("export_list") || "[]";
      exportList = JSON.parse(exportList);
      if(exportList.length == 0) return;
      const selectElement = document.getElementById("export-select");
      selectElement.innerHTML = "";
      for (let i = 0; i < exportList.length; i++) {
        const exportInfo = exportList[i];
        const newOption = document.createElement("option");
        // newOption.value = JSON.stringify(exportInfo);
        newOption.selected = i == exportList.length - 1;
        let exportDate = new Date(exportInfo.time);
        newOption.textContent = `${exportDate.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}`;
        selectElement.appendChild(newOption);
      }
      selectElement.addEventListener("change", onExportSelectChanged);
    }

    function onExportSelectChanged() {
      let localExportList = localStorage.getItem("export_list") || "[]";
      localExportList = JSON.parse(localExportList);
      const selectElement = document.getElementById("export-select");
      const selectedIndex = selectElement.selectedIndex < 0 ? localExportList.length - 1 : selectElement.selectedIndex;
      if(selectedIndex == -1) {
        updateList();
        onLibSelectChanged();
        return 
      }
      let exportData = localExportList[selectedIndex];
      let exportAllLevels = exportData['levels'] || getAllLevels();
      let exportList = exportData['order'];
      let groupNames = exportData['names'] || [];
      let dataArray = window["LevelItemData"];
      for (let i = 0; i < exportList.length; i++) {
        const chapterList = exportList[i];
        let name = i < groupNames.length ? groupNames[i] : dataArray[i] && dataArray[i].name || "组名" + i;
        dataArray[i] = dataArray[i] || {name: name, levels:[]};
        dataArray[i].levels.length = 0;
        for (let j = 0; j < chapterList.length; j++) {
          const tag = chapterList[j];
          dataArray[i].levels[j] = exportAllLevels[tag];
        }
      }
      dataArray.length = exportList.length;
      initSelect();
      updateList();
      onLibSelectChanged();
    }

    let tabIndex = 0;

    function onTab(index) {
      tabIndex = index;
      const tabs = ['tab_order', 'tab_recommend', 'tab_ad'];
      const contents = ['order-content', 'recommend-content', 'ad-content'];
      for (let i = 0; i < tabs.length; i++) {
        if(i == tabIndex){
          document.getElementById(tabs[i]).classList.add('tab_button_select');
        } else {
          document.getElementById(tabs[i]).classList.remove('tab_button_select');
        }
        document.getElementById(contents[i]).style.display = i == tabIndex ? 'flex' : 'none';
      }
      if(tabIndex == 0){
        initSelect(0, tabIndex);
        initExportSelect();
        onExportSelectChanged();
        initSelect();
      }else if(tabIndex == 1){
        initExportGroupSelect();
        updateGroupList();
        updateGroupLevelList();
      }else if(tabIndex == 2){
        initSelect(0, tabIndex);
        initExportAdSelect();
      }
    }

    function showToast(msg) {
      const toast = document.getElementById('toast');
      toast.innerText = msg;
      toast.style.display = 'block';
      setTimeout(function () {
        toast.style.display = 'none';
      }, 3000);
    }

    document.addEventListener("DOMContentLoaded", () => {
      initializeSortableList();
      // showModal();
    });
  </script>
</body>

</html>